#include "../mqserver/mq_host.hpp"
#include <gtest/gtest.h>

class VirtualHostTest : public testing::Test
{
public:
    virtual void SetUp() override
    {
        std::unordered_map<std::string, std::string> umap = std::unordered_map<std::string, std::string>();
        vhp = std::make_shared<csjmq::VirtualHost>("host1", "./data/host1/message/", "./data/host1/data.db");
        // 创建三个交换机
        vhp->declareExchange("exchange1", csjmq::ExchangeType::DIRECT, true, false, umap);
        vhp->declareExchange("exchange2", csjmq::ExchangeType::DIRECT, true, false, umap);
        vhp->declareExchange("exchange3", csjmq::ExchangeType::DIRECT, true, false, umap);

        // 创建三个队列
        vhp->declareQueue("queue1", true, false, false, umap);
        vhp->declareQueue("queue2", true, false, false, umap);
        vhp->declareQueue("queue3", true, false, false, umap);

        // 将交换机和队列进行绑定
        vhp->bind("exchange1", "queue1", ".bind.music");
        vhp->bind("exchange1", "queue2", ".bind.music");
        vhp->bind("exchange1", "queue3", ".bind.music");

        vhp->bind("exchange2", "queue1", ".bind.music");
        vhp->bind("exchange2", "queue2", ".bind.music");
        vhp->bind("exchange2", "queue3", ".bind.music");

        vhp->bind("exchange3", "queue1", ".bind.music");
        vhp->bind("exchange3", "queue2", ".bind.music");
        vhp->bind("exchange3", "queue3", ".bind.music");
    }

    virtual void TearDown() override
    {
    }

public:
    csjmq::VirtualHost::ptr vhp;
};

TEST_F(VirtualHostTest, init_test)
{
    ASSERT_EQ(vhp->existsExchange("exchange1"), true);
    ASSERT_EQ(vhp->existsExchange("exchange2"), true);
    ASSERT_EQ(vhp->existsExchange("exchange3"), true);

    ASSERT_EQ(vhp->existsQueue("queue1"), true);
    ASSERT_EQ(vhp->existsQueue("queue2"), true);
    ASSERT_EQ(vhp->existsQueue("queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange2", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue3"), true);

    ASSERT_EQ(vhp->existsBinding("exchange3", "queue1"), true);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue2"), true);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue3"), true);
}

TEST_F(VirtualHostTest, insert_test)
{
    vhp->BasicPublish("queue1", nullptr, "hello-world-1", true);
    vhp->BasicPublish("queue1", nullptr, "hello-world-2", true);
    vhp->BasicPublish("queue1", nullptr, "hello-world-3", true);

    csjmq::MessagePtr mp1 = vhp->BasicConsume("queue1");
    ASSERT_EQ(mp1->payload().body(), "hello-world-1");
    // vhp->BasicAck("queue1", mp1->payload().properties().id());

    csjmq::MessagePtr mp2 = vhp->BasicConsume("queue1");
    ASSERT_EQ(mp2->payload().body(), "hello-world-2");

    csjmq::MessagePtr mp3 = vhp->BasicConsume("queue1");
    ASSERT_EQ(mp3->payload().body(), "hello-world-3");

    csjmq::MessagePtr mp4 = vhp->BasicConsume("queue1");
    ASSERT_EQ(mp4.get(), nullptr);
}

TEST_F(VirtualHostTest, delete_test)
{
    vhp->deleteExchange("exchange1");
    vhp->existsExchange("exchange1");
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue2"), false);
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue3"), false);

    vhp->deleteQueue("queue1");
    vhp->existsQueue("queue1");
    ASSERT_EQ(vhp->existsBinding("exchange1", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange2", "queue1"), false);
    ASSERT_EQ(vhp->existsBinding("exchange3", "queue1"), false);
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}
